﻿//-----------------------------------------------------------------------
// <copyright file="ToolStripButton.xaml.cs" company="Noboru Project">
//      Copyright (c) Noboru Project. All rights reserved.
//
//      This source code is subject to terms and conditions of the New BSD License (BSD).
//      A copy of the license can be found in the License.html file at the root of this 
//      distribution. If you can not locate the New BSD License (BSD), please send an 
//      email to noboru_adm@live.com.
//      By using this source code in any fashion, you are agreeing to be bound by
//      the terms of the New BSD License (BSD) for Noboru.
//
//      You must not remove this notice, or any other, from this software.
// </copyright>
//-----------------------------------------------------------------------

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Noboru.Windows.Controls.Primitives;

namespace Noboru.Windows.Controls
{
    /// <include file='Documentation\ToolStripButtonDocumentation.uex' path='Members/Member[@for="ToolStripButton.Class"]/*' />
    [TemplatePart(Name = "LayoutPart", Type = typeof(Grid))]
    [TemplatePart(Name = "ImagePart", Type = typeof(Image))]
    [TemplatePart(Name = "TextPart", Type = typeof(TextBlock))]
    [TemplatePart(Name = "HighlightPart", Type = typeof(FrameworkElement))]
    [TemplateVisualState(Name = "Normal", GroupName = "ToolStripButtonCommonStates")]
    [TemplateVisualState(Name = "MouseOver", GroupName = "ToolStripButtonCommonStates")]
    [TemplateVisualState(Name = "MouseOverChecked", GroupName = "ToolStripButtonCommonStates")]
    [TemplateVisualState(Name = "Pressed", GroupName = "ToolStripButtonCommonStates")]
    [TemplateVisualState(Name = "Disabled", GroupName = "ToolStripButtonCommonStates")]
    [TemplateVisualState(Name = "Checked", GroupName = "ToolStripButtonCommonStates")]
    [TemplateVisualState(Name = "Unchecked", GroupName = "ToolStripButtonCommonStates")]
    [TemplateVisualState(Name = "Focused", GroupName = "ToolStripButtonCommonStates")]
    [TemplateVisualState(Name = "Unfocused", GroupName = "ToolStripButtonCommonStates")]
    public class ToolStripButton : ToolStripItem
    {
        /// <include file='Documentation\ToolStripButtonDocumentation.uex' path='Members/Member[@for="ToolStripButton.CornerRadiusProperty"]/*'/>
        public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(ToolStripButton), null);

        private Grid _layoutPart;
        private Image _imagePart;
        private TextBlock _textPart;
        private FrameworkElement _highlightPart;
        private bool _isMouseOver;
        private bool _isMouseLeftButtonDown;
        private bool _hasFocus;
        private bool _hadFocus;

        /// <include file='Documentation\ToolStripButtonDocumentation.uex' path='Members/Member[@for="ToolStripButton.Constructor"]/*' />
        public ToolStripButton()
        {
            ////this.SizeChanged += new SizeChangedEventHandler(this.ToolStripButton_SizeChanged);
            this.DefaultStyleKey = typeof(ToolStripButton);
        }

        /// <include file='Documentation\ToolStripButtonDocumentation.uex' path='Members/Member[@for="ToolStripButton.CornerRadius"]/*'/>
        public CornerRadius CornerRadius
        {
            get
            {
                return (CornerRadius)this.GetValue(CornerRadiusProperty);
            }

            set
            {
                this.SetValue(CornerRadiusProperty, value);
            }
        }

        protected Grid LayoutPart
        {
            get
            {
                return this._layoutPart;
            }

            set
            {
                if (this._layoutPart != null)
                {
                    this._layoutPart.MouseLeftButtonDown -= new MouseButtonEventHandler(this.LayoutPart_MouseLeftButtonDown);
                    this._layoutPart.MouseEnter -= new MouseEventHandler(this.LayoutPart_MouseEnter);
                    this._layoutPart.MouseLeave -= new MouseEventHandler(this.LayoutPart_MouseLeave);
                    this._layoutPart.MouseLeftButtonUp -= new MouseButtonEventHandler(this.LayoutPart_MouseLeftButtonUp);
                }

                if (value != null)
                {
                    this._layoutPart = value;

                    this._layoutPart.MouseLeftButtonDown += new MouseButtonEventHandler(this.LayoutPart_MouseLeftButtonDown);
                    this._layoutPart.MouseEnter += new MouseEventHandler(this.LayoutPart_MouseEnter);
                    this._layoutPart.MouseLeave += new MouseEventHandler(this.LayoutPart_MouseLeave);
                    this._layoutPart.MouseLeftButtonUp += new MouseButtonEventHandler(this.LayoutPart_MouseLeftButtonUp);
                }
                else
                {
                    this._layoutPart = null;
                }
            }
        }

        protected FrameworkElement HighlightPart
        {
            get
            {
                return this._highlightPart;
            }

            set
            {
                this._highlightPart = value;
            }
        }

        protected Image ImagePart
        {
            get
            {
                return this._imagePart;
            }

            set
            {
                FrameworkElement oldImagePart = this._imagePart;
                if (oldImagePart != null)
                {
                }

                this._imagePart = value;

                if (this._imagePart != null)
                {
                }
            }
        }

        protected TextBlock TextPart
        {
            get
            {
                return this._textPart;
            }

            set
            {
                FrameworkElement oldTextPart = this._textPart;
                if (oldTextPart != null)
                {
                }

                this._textPart = value;

                if (this._textPart != null)
                {
                }
            }
        }

        /// <include file='Documentation\ToolStripButtonDocumentation.uex' path='Members/Member[@for="ToolStripButton.OnApplyTemplate"]/*' />
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            this.LayoutPart = (Grid)GetTemplateChild("LayoutPart");
            this.ImagePart = (Image)GetTemplateChild("ImagePart");
            this.TextPart = (TextBlock)GetTemplateChild("TextPart");
            this.HighlightPart = (FrameworkElement)GetTemplateChild("HighlightPart");

            this.DetermineLayout();
            this.ApplyCommonState(false);
        }

        /// <param name="e">The data for the event.</param>
        protected override void OnGotFocus(System.Windows.RoutedEventArgs e)
        {
            this._hasFocus = true;
            this.ApplyCommonState(true);

            base.OnGotFocus(e);
        }

        protected override void OnIsEnabledChanged(DependencyPropertyChangedEventArgs e)
        {
            if (!this.IsEnabled)
            {
                this._isMouseOver = false;
            }

            base.OnIsEnabledChanged(e);

            this.ApplyCommonState(false);
        }

        protected override void OnIsCheckedChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnIsCheckedChanged(e);

            this.ApplyCommonState(true);
        }

        /// <param name="e">The data for the event.</param>
        protected override void OnLostFocus(System.Windows.RoutedEventArgs e)
        {
            if (this._hasFocus)
            {
                this._hasFocus = false;
                this._hadFocus = true;
                this.ApplyCommonState(true);
            }

            base.OnLostFocus(e);
        }

        /// <include file='Documentation\ToolStripButtonDocumentation.uex' path='Members/Member[@for="ToolStripButton.OnTextChanged"]/*' />
        protected override void OnTextChanged(DependencyPropertyChangedEventArgs e)
        {
            if (this._textPart != null)
            {
                this._textPart.Text = this.Text;
            }

            base.OnTextChanged(e);
        }

        private static void PropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            ((ToolStripButton)sender).OnPropertyChanged(e);
        }

        private void DetermineLayout()
        {
            if (this._imagePart != null)
            {
                this._imagePart.Source = this.ImageSource;
            }

            if (this._textPart != null)
            {
                this._textPart.Text = this.Text;
            }
        }

        private void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            if (this._imagePart != null)
            {
                this._imagePart.Source = this.ImageSource;
            }
        }

        private void LayoutPart_MouseEnter(object sender, MouseEventArgs e)
        {
            this._isMouseOver = true;
            this.ApplyCommonState(true);
        }

        private void LayoutPart_MouseLeave(object sender, MouseEventArgs e)
        {
            this._isMouseOver = false;
            this.ApplyCommonState(true);
        }

        private void LayoutPart_MouseLeftButtonDown(object sender, MouseEventArgs e)
        {
            this._layoutPart.CaptureMouse();
            this._isMouseLeftButtonDown = true;
            this.ApplyCommonState(false);
        }

        private void LayoutPart_MouseLeftButtonUp(object sender, MouseEventArgs e)
        {
            this._layoutPart.ReleaseMouseCapture();
            this._isMouseLeftButtonDown = false;
            this.ApplyCommonState(true);

            if (this._isMouseOver)
            {
                this.OnClick(new RoutedEventArgs());
            }
        }

        private void ToolStripButton_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (this._highlightPart != null)
            {
                this._highlightPart.Width = e.NewSize.Width;
                this._highlightPart.Height = e.NewSize.Height;
            }
        }

        private void ApplyCommonState(bool useTransitions)
        {
            if (this.IsEnabled)
            {
                if (this._isMouseLeftButtonDown)
                {
                    VisualStateManager.GoToState(this, "Pressed", useTransitions);
                }
                else
                {
                    if (this._hasFocus)
                    {
                        if (this.IsChecked.Value)
                        {
                            VisualStateManager.GoToState(this, "FocusedChecked", useTransitions);
                        }
                        else
                        {
                            VisualStateManager.GoToState(this, "Focused", useTransitions);
                        }
                    }
                    else if (this._hadFocus && (!this.IsChecked.Value))
                    {
                        this._hadFocus = false;
                        VisualStateManager.GoToState(this, "Unfocused", useTransitions);
                    }
                    else
                    {
                        if (this._isMouseOver)
                        {
                            if (this.IsChecked.Value)
                            {
                                VisualStateManager.GoToState(this, "MouseOverChecked", useTransitions);
                            }
                            else
                            {
                                VisualStateManager.GoToState(this, "MouseOver", useTransitions);
                            }
                        }
                        else
                        {
                            if (this.IsChecked.Value)
                            {
                                VisualStateManager.GoToState(this, "Checked", useTransitions);
                            }
                            else
                            {
                                VisualStateManager.GoToState(this, "Normal", useTransitions);
                            }
                        }
                    }
                }
            }
            else
            {
                VisualStateManager.GoToState(this, "Disabled", useTransitions);
            }
        }
    }
}
